Programming Graphics in Assembler
This is part 1 of a tutorial designed to help teach newcomers to the demoscene get started in writing in Assembler up to creating some simple graphics effects. If I get good feedback from these sessions then I will continue to some basic demo effects.
It is assumed that you have some experience in another language before hand to a fairly advanced level, maybe C or Pascal, and have a bit of basic maths (GCSE level here in England) and that you want to start to learn some Assembler to help you in your coding.
Disclaimer
The author accepts no responsibility for any damage caused by the use of this tutorial or any files created using it.
Requirements
All programs in this tutorial were compiled and created using a 386 and the following programs:
A86 Assembler - Shareware! Assembler Laboratory v1.2 - Shareware!
As you can see I have tried to keep to downloadable programs to allow everyone the ability to get started straight away. Please register these programs if you intend to continue using them.
PART 1 - The Assembler language
Assembler is an interesting language with many good and bad points to it, but whatever your opinion it will never die as a use of getting fast, efficient code into your DOS-based programs (Direct-X for Windows 95 is used far more than ASM). I found the easiest way of learning Assembler was to think of it as just another programming language with its own special variables and functions.
This is fine to begin with but to truly become a master you should look into buying a proper book on the subject.
Ok, to begin with we shall look at the things you will be using a lot in your programs... the memory registers.
Registers
The memory registers are places in memory where you and the computer place values in order for you to comunicate with it. It is not completely true to say they are like pre-defined variables but at the moment try to think of them like that.
There are 14 seperate 16-bit registers used by the 8086 family, these can be grouped into four catagories:
(1) General - purpose registers (2) Segment Registers (3) Offset registers (4) The flags register
Each type of register has its own special function:
(1) General-Purpose Regisers
There are four registers that you can use for "everyday" usage, namely AX, BX, CX and DX. Being 16 bit registers they are, what we call in the trade, WORD registers meaning they are twice the size of a byte, which in turn is eight times the size of a bit. Ah, now you're confused, aren't you?... I'll explain:
The smallest size a piece of data can take is a BIT, bit is short for BINARY DIGIT and it is the size of 1 digit in string of binary code, e.g. in 1001001 each 1 or 0 has the size of 1 bit.
Ok, I mentioned a "byte" earlier. A byte is the size of 8 BITS. One character in a typical ASCII document is 1 byte big.
Next, is the WORD, a word is the size of 2 bytes or 16 bits. NB: WORD is NOT the next size up from the BYTE, but I have never needed to know about the previous sizes so I won't bore you with them. If you really want to know, mail me.
Next is the DOUBLE WORD, which is twice the size of a word, or 32 bits.
Ok, I was talking about registers. General-Purpose Registers are used kind of like variables in high-level programming languages, values are put into them for storage, counting and other purposes. That's why they are general-purpose registers (duh). If you only want to access a byte of this word value, each register can be divided up into High and Low values. AH and AL for example and the upper and lower bytes of the register AX. I can't think of anything else to write about these but if I do you'll be first to know(!).
(2) Segment Registers
There are 4 segments registers up for grabs, CS DS, ES and SS. CS is used to point at the segment of your program where the main code, the procedures, etc. are stored, namely the Code Segment. DS points to the Data segment of your program, all the values predefined into the program, like strings and numerical data. ES points to anything Extra (often more data) and SS points to your program's stack. I might go into these in more detail later but it is not essential at this stage.
(3) Offset Registers
The offset registers are used to point to certain points in the above segments and memory. They are SP (stack pointer), BP (Base pointer), DI (Destination Index) and IP (the instruction pointer), each is used to point to a part of the above segments, SP-SS, BP-SS, SI-DS, DI-ES, IP-CS.
(4) Flags
Flags are rarely used consciously but you mainly use them to show if a built in operation is succesful or not.
Read the last bit over and over until you understand it because it is quite important.
Ok, I think you are ready to look at your first program and for us to analyze it:
;----------------------------------
; RETURN.ASM
;----------------------------------
; This program does nothing but exit
; to dos.
DOSSEG
.stack 200H
.model SMALL
.DATA
.CODE
BEGIN:
mov ax,04c00H
int 21h
END BEGIN
;------------------------------------
Ok, don't panic. I will go through it slowly. To start with is the name of the program commented out using a ';' character. This character causes anything after it to be ignored by the Assembler, just like // in C++. It's good to start with the name of the program and some brief comment on its function so when you build up a big library of source code you will know what is what.
DOSSEG is the next line. This sets up the Segments CS, DS, etc as explained before in DOS standard mode. This is fine for whatever you will want to do.
.STACK 200H states the size of the stack segment pointed to by SS. 200H is fine to begin with but as your programs get larger, you will need a bigger stack.
.MODEL SMALL tells the Assembler how to treat the code and data segments CS and DS point to. It also means that the code can be linked to high-level programs with ease. This only needs to be used if you use DOSSEG to organise your segments. Small is fine for most applications but whip it up to LARGE if you experience errors.
.DATA tells the Assembler you have started your data segment, in this code we have no data yet.
.CODE tells the Assembler that you have started your CODE segment. We have 2 commands that I will go into in a minute.
BEGIN and END BEGIN show the Assembler where to start and end when running your program, i.e., start at BEGIN and end at END BEGIN.
Right, MOV is the first command we have encountered so far. Commands such as these are called OPERANDS and are used like funtions in high-level languages. Look how it is written:
MOV ax,04C00H
Mov is short for MOVE and the command above MOVEs the value of 04C00H into the register AX. Wow. Generally it is written as:
MOV destination, source
INT 21H means that you are calling a dos INTERRUPT. Interrupts are functions already built into your computer's BIOS. These are simple functions designed to do different things for your computer, like putting a character onto the screen, loading and saving files, etc. INT 21H is a whole array of special functions made by DOS for easy handling of the keyboard, etc. MOVing 04C00H into AX tells the interrupt that we want function number 4Ch - Exit to DOS in this case. You can by big books like the DOS PROGRAMMERS REFERENCE, etc to list all the interrupts for you, or you can download them. Maybe if I am feeling up to it I will do the same.
Final words
If you are having troubles E-MAIL me and I will try and help you personally.
C U